home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / muds / pennmush.000 / pennmush-1.50-p8-linux.tar / pennmush / create.c < prev    next >
C/C++ Source or Header  |  1993-03-17  |  14KB  |  549 lines

  1. /* create.c */
  2.  
  3. /* Commands that create new objects */
  4. #include <string.h>
  5. #include "config.h"
  6. #include "db.h"
  7. #include "attrib.h"
  8. #include "interface.h"
  9. #include "externs.h"
  10.  
  11. /* utility for open and link */
  12. static dbref parse_linkable_room(player, room_name)
  13.     dbref player;
  14.     const char *room_name;
  15. {
  16.   dbref room;
  17.   /* skip leading NUMBER_TOKEN if any */
  18.   if (*room_name == NUMBER_TOKEN)
  19.     room_name++;
  20.   /* parse room */
  21.   if (!strcasecmp(room_name, "here")) {
  22.     room = Location(player);
  23.   } else if (!strcasecmp(room_name, "home")) {
  24.     return HOME;                /* HOME is always linkable */
  25.   } else {
  26.     room = parse_dbref(room_name);
  27.   }
  28.  
  29.   /* check room */
  30.   if (!GoodObject(room)) {
  31.     notify(player, "That is not a valid object.");
  32.     return NOTHING;
  33.   } else if (Going(room)) {
  34.     notify(player, "That room is being destroyed. Sorry.");
  35.     return NOTHING;
  36.   } else if (!can_link_to(player, room)) {
  37.     notify(player, "You can't link to that.");
  38.     return NOTHING;
  39.   } else {
  40.     return room;
  41.   }
  42. }
  43.  
  44. int do_real_open(player, direction, linkto, pseudo)
  45.     dbref player;
  46.     const char *direction;
  47.     const char *linkto;
  48.     dbref pseudo;        /* a phony location for a player if a back
  49.                  * exit is needed */
  50. {
  51.     /* function creates an exit. Note that it returns 0 and NOT -1
  52.      * if it fails.
  53.      */
  54.  
  55.   dbref loc = (pseudo != NOTHING) ? pseudo : Location(player);
  56.   dbref new_exit;
  57.   if ((loc == NOTHING) || (Typeof(loc) != TYPE_ROOM)) {
  58.     notify(player, "Sorry you can only make exits out of rooms.");
  59.     return 0;
  60.   }
  61.  
  62. #ifdef RESTRICTED_BUILDING
  63.   if (!Builder(player)) {
  64.     notify(player, "That command is restricted to authorized builders.");
  65.     return 0;
  66.   }
  67. #endif                /* RESTRICTED_BUILDING */
  68. #ifdef GUEST_RESTRICT
  69.   if (Guest(player)) {
  70.     notify(player, "Guests are not allowed to build.");
  71.     return 0;
  72.   }
  73. #endif
  74.  
  75.   if(!*direction) {
  76.     notify(player, "Open where?");
  77.     return 0;
  78.   } else if (!ok_name(direction)) {
  79.     notify(player, "That's a strange name for an exit!");
  80.     return 0;
  81.   }
  82.   if (!controls(player, loc)) {
  83.     notify(player, "Permission denied.");
  84.   } else if (can_pay_fees(player, EXIT_COST)) {
  85.     /* create the exit */
  86.     new_exit = new_object();
  87.  
  88.     /* initialize everything */
  89.     SET(db[new_exit].name, direction);
  90.     Owner(new_exit) = Owner(player);
  91.     Zone(new_exit) = Zone(player);
  92.     Exits(new_exit) = loc;
  93.     Flags(new_exit) = TYPE_EXIT;
  94.     Flags(new_exit) |= options.exit_flags;
  95.     Toggles(new_exit) |= options.exit_toggles;
  96.  
  97.     /* link it in */
  98.     PUSH(new_exit, Exits(loc));
  99.  
  100.     /* and we're done */
  101.     notify(player, "Opened.");
  102.  
  103.     /* check second arg to see if we should do a link */
  104.     if (linkto && *linkto != '\0') {
  105.       notify(player, "Trying to link...");
  106.       if ((loc = parse_linkable_room(player, linkto)) != NOTHING) {
  107.     if (!payfor(player, LINK_COST)) {
  108.       notify(player, tprintf("You don't have enough %s to link.", MONIES));
  109.     } else {
  110.       /* it's ok, link it */
  111.       Location(new_exit) = loc;
  112.       notify(player, "Linked.");
  113.     }
  114.       }
  115.     }
  116.     return new_exit;
  117.   }
  118.   return 0;
  119. }
  120.  
  121. void do_open(player,direction,links)
  122.     dbref player;
  123.     const char *direction;
  124.     const char *links[];
  125. {
  126.   do_real_open(player, direction, links[1], NOTHING);
  127.   if(links[2]) {
  128.     do_real_open(player, links[2], tprintf("%d",Location(player)),
  129.              parse_linkable_room(player, links[1]));
  130.   }
  131. }
  132.  
  133. void do_unlink(player, name)
  134.     dbref player;
  135.     const char *name;
  136. {
  137.   dbref exit_l;
  138.   init_match(player, name, TYPE_EXIT);
  139.   match_exit();
  140.   match_here();
  141.   if (Wizard(player)) {
  142.     match_absolute();
  143.   } else {
  144.     match_controlled_absolute();
  145.   }
  146.   switch (exit_l = match_result()) {
  147.     case NOTHING:
  148.       notify(player, "Unlink what?");
  149.       break;
  150.     case AMBIGUOUS:
  151.       notify(player, "I don't know which one you mean!");
  152.       break;
  153.     default:
  154.       if (!controls(player, exit_l)) {
  155.     notify(player, "Permission denied.");
  156.       } else {
  157.     switch (Typeof(exit_l)) {
  158.       case TYPE_EXIT:
  159.         db[exit_l].location = NOTHING;
  160.         notify(player, "Unlinked.");
  161.         break;
  162.       case TYPE_ROOM:
  163.         db[exit_l].location = NOTHING;
  164.         notify(player, "Dropto removed.");
  165.         break;
  166.       default:
  167.         notify(player, "You can't unlink that!");
  168.         break;
  169.     }
  170.       }
  171.   }
  172. }
  173.  
  174. void do_link(player, name, room_name)
  175.     dbref player;
  176.     const char *name;
  177.     const char *room_name;
  178. {
  179.     /* Use this to link to a room that you own. 
  180.      * It seizes ownership of the exit and costs 1 penny,
  181.      * plus a penny transferred to the exit owner if they aren't you.
  182.      * You must own the linked-to room AND specify it by room number.
  183.      */
  184.  
  185.   dbref thing;
  186.   dbref room;
  187.  
  188.   if (!room_name || !*room_name) {
  189.       do_unlink(player, name);
  190.       return;
  191.   }
  192.  
  193.   if (Typeof(Location(player)) == TYPE_EXIT) {
  194.     notify(player, "You somehow wound up in a exit. No biscuit.");
  195.     return;
  196.   }
  197.   init_match(player, name, TYPE_EXIT);
  198.   match_everything();
  199.  
  200.   if ((thing = noisy_match_result()) != NOTHING) {
  201.     switch (Typeof(thing)) {
  202.       case TYPE_EXIT:
  203.     if((room = parse_linkable_room(player, room_name)) == NOTHING)
  204.       return;
  205.     if ((room != HOME) &&
  206.         !controls(player, room) && !LinkOk(room)) {
  207.       notify(player, "Permission denied.");
  208.       break;
  209.     }
  210.     /* we're ok, check the usual stuff */
  211.     if (Location(thing) != NOTHING) {
  212.       if (controls(player, thing)) {
  213.         if (Typeof(Location(thing)) == TYPE_PLAYER) {
  214.           notify(player, "That exit is being carried.");
  215.         } else {
  216.           notify(player, "That exit is already linked.");
  217.         }
  218.       } else {
  219.         notify(player, "Permission denied.");
  220.       }
  221.     } else {
  222.       /* handle costs */
  223.       if (db[thing].owner == Owner(player)) {
  224.         if (!payfor(player, LINK_COST)) {
  225.           notify(player, tprintf("It costs %d %s to link this exit.",
  226.                      LINK_COST,
  227.                                      ((LINK_COST == 1) ? MONEY : MONIES)));
  228.           return;
  229.         }
  230.       } else {
  231.         if (!payfor(player, LINK_COST + EXIT_COST)) {
  232.           int a = 0;
  233.           notify(player, tprintf("It costs %d %s to link this exit.",
  234.                      (a = LINK_COST+EXIT_COST),
  235.                      ((a == 1) ? MONEY : MONIES)));
  236.           return;
  237. #ifdef RESTRICTED_BUILDING
  238.         } else if (!Builder(player)) {
  239.           notify(player, "Only authorized builders may seize exits.");
  240.           return;
  241. #endif /* RESTRICTED_BUILDING */
  242. #ifdef GUEST_RESTRICT
  243.         } else if (Guest(player)) {
  244.           notify(player, "Guests are not allowed to build.");
  245.           return;
  246. #endif                /* GUEST_RESTRICT */
  247.         } else {
  248.           /* pay the owner for his loss */
  249.           giveto(db[thing].owner, EXIT_COST);
  250.         }
  251.       }
  252.  
  253.       /* link has been validated and paid for; do it */
  254.       db[thing].owner = Owner(player);
  255.       db[thing].zone = db[player].zone;
  256.       Location(thing) = room;
  257.  
  258.       /* notify the player */
  259.       notify(player, "Linked.");
  260.     }
  261.     break;
  262.       case TYPE_PLAYER:
  263.       case TYPE_THING:
  264.     init_match(player, room_name, NOTYPE);
  265.     match_everything();
  266.     if ((room = noisy_match_result()) < 0) {
  267.       notify(player, "No match.");
  268.       return;
  269.     }
  270.     if (Typeof(room) == TYPE_EXIT) {
  271.       notify(player, "That is an exit.");
  272.       return;
  273.     }
  274.     if (thing == room) {
  275.       notify(player, "You may not link something to itself.");
  276.       return;
  277.     }
  278.     /* abode */
  279.     if (!controls(player, room) && !Abode(room)) {
  280.       notify(player, "Permission denied.");
  281.       break;
  282.     }
  283.     if (!controls(player, thing)) {
  284.       notify(player, "Permission denied.");
  285.     } else if (room == HOME) {
  286.       notify(player, "Can't set home to home.");
  287.     } else {
  288.       /* do the link */
  289.       db[thing].exits = room;    /* home */
  290.       notify(player, "Home set.");
  291.     }
  292.     break;
  293.       case TYPE_ROOM:
  294.     if ((room = parse_linkable_room(player, room_name)) == NOTHING)
  295.       return;
  296.  
  297.     if ((room != HOME) && (Typeof(room) != TYPE_ROOM)) {
  298.       notify(player, "That is not a room!");
  299.       return;
  300.     }
  301.     if (!controls(player, thing)) {
  302.       notify(player, "Permission denied.");
  303.     } else {
  304.       /* do the link, in location */
  305.       Location(thing) = room;    /* dropto */
  306.       notify(player, "Dropto set.");
  307.     }
  308.     break;
  309.       default:
  310.     notify(player, "Internal error: weird object type.");
  311.     fprintf(stderr, "PANIC weird object: Typeof(%d) = %d\n",
  312.         thing, Typeof(thing));
  313.     break;
  314.     }
  315.   }
  316. }
  317.  
  318. /* use this to create a room */
  319. dbref do_dig(player, name, argv, tport)
  320.     dbref player;
  321.     const char *name;
  322.     char *argv[];
  323.     int tport;            /* @tel player to new location? */
  324. {
  325.   dbref room;
  326.  
  327. #ifdef RESTRICTED_BUILDING
  328.   if (!Builder(player)) {
  329.     notify(player, "That command is restricted to authorized builders.");
  330.     return NOTHING;
  331.   }
  332. #endif                /* RESTRICTED_BUILDING */
  333. #ifdef GUEST_RESTRICT
  334.   if (Guest(player)) {
  335.     notify(player, "Guests are not allowed to build.");
  336.     return NOTHING;
  337.   }
  338. #endif
  339.  
  340.   /* we don't need to know player's location!  hooray! */
  341.   if (*name == '\0') {
  342.     notify(player, "Dig what?");
  343.   } else if (!ok_name(name)) {
  344.     notify(player, "That's a silly name for a room!");
  345.   } else if (can_pay_fees(player, ROOM_COST)) {
  346.     room = new_object();
  347.  
  348.     /* Initialize everything */
  349.     SET(db[room].name, name);
  350.     Owner(room) = Owner(player);
  351.     Zone(room) = Zone(player);
  352.     Flags(room) = TYPE_ROOM;
  353.     Flags(room) |= options.room_flags;
  354.     Toggles(room) |= options.room_toggles;
  355.  
  356.     notify(player,
  357.        tprintf("%s created with room number %d.", name, room));
  358.     if (argv[1] && *argv[1]) {
  359.       char nbuff[MAX_COMMAND_LEN];
  360.       sprintf(nbuff, "%d", room);
  361.       do_real_open(player, argv[1], nbuff, NOTHING);
  362.     }
  363.     if (argv[2] && *argv[2]) {
  364.       char nbuff[MAX_COMMAND_LEN];
  365.       sprintf(nbuff, "%d", Location(player));
  366.       do_real_open(player, argv[2], nbuff, room);
  367.     }
  368.     if (tport)
  369.       safe_tel(player, room);    /* if flag, move the player */
  370.     return room;
  371.   }
  372.   return NOTHING;
  373. }
  374.  
  375. /* use this to create an object */
  376. dbref do_create(player, name, cost)
  377.     dbref player;
  378.     char *name;
  379.     int cost;
  380. {
  381.   dbref loc;
  382.   dbref thing;
  383.  
  384. #ifndef FREE_OBJECTS
  385. #ifdef RESTRICTED_BUILDING
  386.   if (!Builder(Owner(player))) {
  387.     notify(player, "That command is restricted to authorized builders.");
  388.     return NOTHING;
  389.   }
  390. #endif  /* RESTRICTED_BUILDING */
  391. #endif  /* FREE_OBJECTS */
  392.  
  393. #ifdef GUEST_RESTRICT
  394.   if (Guest(player)) {
  395.     notify(player, "Guests are not allowed to build.");
  396.     return NOTHING;
  397.   }
  398. #endif
  399.  
  400.   if (*name == '\0') {
  401.     notify(player, "Create what?");
  402.     return NOTHING;
  403.   } else if (!ok_name(name)) {
  404.     notify(player, "That's a silly name for a thing!");
  405.     return NOTHING;
  406.   } else if (cost < OBJECT_COST) {
  407.     cost = OBJECT_COST;
  408.   }
  409.   if (can_pay_fees(player, cost)) {
  410.     /* create the object */
  411.     thing = new_object();
  412.  
  413.     /* initialize everything */
  414.     SET(Name(thing), name);
  415.     Location(thing) = player;
  416.     Owner(thing) = Owner(player);
  417.     Zone(thing) = Zone(player);
  418.     s_Pennies(thing, OBJECT_ENDOWMENT(cost));
  419.     Flags(thing) = TYPE_THING;
  420.     Flags(thing) |= options.thing_flags;
  421.     Toggles(thing) |= options.thing_toggles;
  422.  
  423.     /* endow the object */
  424.     if(Wizard(player)) {
  425.       if(Pennies(thing) > MAX_WIZ_OBJECT_ENDOWMENT)
  426.     s_Pennies(thing, MAX_WIZ_OBJECT_ENDOWMENT);
  427.     } else
  428.       if (Pennies(thing) > MAX_OBJECT_ENDOWMENT)
  429.         s_Pennies(thing, MAX_OBJECT_ENDOWMENT);
  430.     /* home is here (if we can link to it) or player's home */
  431.     if ((loc = Location(player)) != NOTHING &&
  432.     (controls(player, loc) ||
  433.      IS(loc, TYPE_ROOM, ROOM_ABODE))) {
  434.       db[thing].exits = loc;    /* home */
  435.     } else {
  436.       db[thing].exits = db[player].exits;    /* home */
  437.     }
  438.  
  439.     /* link it in */
  440.     PUSH(thing, db[player].contents);
  441.  
  442.     /* and we're done */
  443.     notify(player, tprintf("Created: Object #%d.", thing));
  444.     return thing;
  445.   }
  446.   return NOTHING;
  447. }
  448.  
  449.  
  450. void do_clone(player, name)
  451.     dbref player;
  452.     char *name;
  453. {
  454.     dbref clone, thing;
  455.  
  456. #ifdef GUEST_RESTRICT
  457.     if (Guest(player)) {
  458.     notify(player, "Guests are not allowed to build.");
  459.     return;
  460.     }
  461. #endif
  462.  
  463.     init_match(player, name, NOTYPE);
  464.     match_everything();
  465.  
  466.     thing = noisy_match_result();
  467.     if ((thing == NOTHING))
  468.     return;
  469.  
  470.     if (!controls(player, thing)) {
  471.     notify(player, "Permission denied.");
  472.     return;
  473.     }
  474.  
  475.     /* don't allow cloning of destructed things */
  476.     if (Going(thing)) {
  477.     notify(player, "There's nothing left of it to clone!");
  478.     return;
  479.     }
  480.  
  481.     /* make sure owner can afford it */
  482.     switch (Typeof(thing)) {
  483.       case TYPE_THING:
  484. #ifdef RESTRICTED_BUILDING
  485. #ifndef FREE_OBJECTS
  486.     if (!Builder(player)) {
  487.         notify(player, "Command is for builders only.");
  488.         return;
  489.     }
  490. #endif
  491. #endif
  492.     if (can_pay_fees(player, OBJECT_DEPOSIT(Pennies(thing)))) {
  493.         clone = new_object();
  494.         memcpy(&db[clone], &db[thing], sizeof(struct object));
  495.         db[clone].name = NULL;
  496.         SET(db[clone].name, Name(thing));
  497.         s_Pennies(clone, Pennies(thing));
  498.         atr_cpy(clone, thing);
  499.         db[clone].key = dup_bool(db[thing].key);
  500.         db[clone].enterkey = dup_bool(db[thing].enterkey);
  501.         db[clone].usekey = dup_bool(db[thing].usekey);
  502.         db[clone].zone = db[thing].zone;
  503.         db[clone].parent = db[thing].parent;
  504.         db[clone].flags &= ~WIZARD;
  505. #ifdef ROYALTY_FLAG
  506.         db[clone].flags &= ~ROYALTY;
  507. #endif
  508.         db[clone].powers = 0;    /* zap powers */
  509.  
  510.         db[clone].contents = db[clone].location = db[clone].next = NOTHING;
  511.         notify(player, tprintf("Cloned: Object #%d.", clone));
  512.         moveto(clone, Location(player));
  513.         did_it(player, clone, NULL, NULL, NULL, NULL, "ACLONE", NOTHING);
  514.     }
  515.     break;
  516.       case TYPE_EXIT:
  517. #ifdef RESTRICTED_BUILDING
  518.     if (!Builder(player)) {
  519.         notify(player, "Command is for builders only.");
  520.         return;
  521.     }
  522. #endif
  523.     clone = do_real_open(player, Name(thing),
  524.                  tprintf("%d", Location(thing)), NOTHING);
  525.     if (!clone)
  526.         return;
  527.     else {
  528.         atr_cpy(clone, thing);
  529.         db[clone].key = dup_bool(Key(thing));
  530.         db[clone].enterkey = dup_bool(Enterkey(thing));
  531.         db[clone].usekey = dup_bool(Usekey(thing));
  532.         db[clone].zone = Zone(thing);
  533.         db[clone].parent = Parent(thing);
  534.         Flags(clone) = Flags(thing);
  535.         Flags(clone) &= ~WIZARD;
  536. #ifdef ROYALTY_FLAG
  537.         Flags(clone) &= ~ROYALTY;
  538. #endif
  539.         db[clone].powers = 0;    /* zap powers */
  540.         notify(player, "Exit cloned.");
  541.     }
  542.     break;
  543.       default:
  544.     notify(player, "You can only clone things and exits.");
  545.     return;
  546.     }
  547.  
  548. }
  549.